using System.Collections;
using UnityEngine;
using GGameFramework.Core.Pool;
using System.Collections.Generic;

namespace GGameFramework.Core.Pool.Examples
{
    /// <summary>
    /// 引用类型对象池测试示例
    /// </summary>
    public class ReferencePoolTestExample : MonoBehaviour
    {
        [Header("引用类型对象池测试")]
        [SerializeField] private int spawnCount = 10;
        [SerializeField] private int recycleCount = 5;
        
        private IReferencePool<TestReferenceObject> _referencePool;
        private List<TestReferenceObject> _activeObjects = new List<TestReferenceObject>();
        
        [System.Serializable]
        public class TestReferenceObject :ReferencePoolable
        {
            public int id;
            public string name;
            public bool isActive;
            
            public TestReferenceObject()
            {
                id = UnityEngine.Random.Range(1, 1000);
                name = $"TestObj_{id}";
                isActive = true;
            }
            
            public void Reset()
            {
                isActive = false;
            }
        }
        
        [ContextMenu("创建引用类型对象池")]
        public void CreateReferencePool()
        {
            _referencePool = FrameworkEntry.GetModule<PoolManager>().CreateReferencePool<TestReferenceObject>(
                createFunc: () => new TestReferenceObject(),
                onSpawn: obj => { Debug.Log($"引用对象被取出: {obj.name}"); },
                onRecycle: obj => { Debug.Log($"引用对象被回收: {obj.name}"); obj.Reset(); },
                onDestroy: obj => { Debug.Log($"引用对象被销毁: {obj.name}"); },
                initialCapacity: 5,
                maxSize: 20,
                isDynamic: true
            );
            
            Debug.Log("引用类型对象池创建成功");
        }
        
        [ContextMenu("从引用类型对象池获取对象")]
        public void SpawnFromReferencePool()
        {
            if (_referencePool == null)
            {
                Debug.LogError("请先创建引用类型对象池");
                return;
            }
            
            for (int i = 0; i < spawnCount; i++)
            {
                var obj = _referencePool.Spawn();
                _activeObjects.Add(obj);
                Debug.Log($"获取引用对象: {obj.name}, 池大小: {_referencePool.Count}");
            }
        }
        
        [ContextMenu("回收引用类型对象")]
        public void RecycleToReferencePool()
        {
            if (_referencePool == null)
            {
                Debug.LogError("请先创建引用类型对象池");
                return;
            }
            
            int count = Mathf.Min(recycleCount, _activeObjects.Count);
            for (int i = 0; i < count; i++)
            {
                if (_activeObjects.Count > 0)
                {
                    var obj = _activeObjects[_activeObjects.Count - 1];
                    _activeObjects.RemoveAt(_activeObjects.Count - 1);
                    _referencePool.Recycle(obj);
                    Debug.Log($"回收引用对象: {obj.name}, 池大小: {_referencePool.Count}");
                }
            }
        }
        
        [ContextMenu("获取引用类型对象池统计")]
        public void GetReferencePoolStatistics()
        {
            if (_referencePool == null)
            {
                Debug.LogError("请先创建引用类型对象池");
                return;
            }
            
            var stats = _referencePool.Statistics;
            Debug.Log($"引用类型对象池统计:");
            Debug.Log($"  总取出次数: {stats.TotalSpawned}");
            Debug.Log($"  总回收次数: {stats.TotalRecycled}");
            Debug.Log($"  最大并发数: {stats.MaxConcurrent}");
            Debug.Log($"  池溢出次数: {stats.PoolOverflows}");
            Debug.Log($"  当前池大小: {_referencePool.Count}");
        }
    }
    
    /// <summary>
    /// GameObject对象池测试示例
    /// </summary>
    public class GameObjectPoolTestExample : MonoBehaviour
    {
        [Header("GameObject对象池测试")]
        [SerializeField] private GameObjectPoolable prefab;
        [SerializeField] private int spawnCount = 10;
        [SerializeField] private int recycleCount = 5;
        
        private IGameObjectPool<TestGameObjectPoolable> _gameObjectPool;
        private List<TestGameObjectPoolable> _activeObjects = new List<TestGameObjectPoolable>();
        
        [System.Serializable]
        public class TestGameObjectPoolable : GameObjectPoolable
        {
            public int id;
            public string displayName;
            
            public override void OnSpawn()
            {
                base.OnSpawn();
                id = UnityEngine.Random.Range(1, 1000);
                displayName = $"GameObj_{id}";
                Debug.Log($"GameObject被取出: {displayName}");
            }
            
            public override void OnRecycle()
            {
                base.OnRecycle();
                Debug.Log($"GameObject被回收: {displayName}");
            }
        }
        
        [ContextMenu("创建GameObject对象池")]
        public void CreateGameObjectPool()
        {
            if (prefab == null)
            {
                Debug.LogError("请先设置预制体");
                return;
            }
            
            var poolManager = FrameworkEntry.GetModule<PoolManager>();
            _gameObjectPool = poolManager.CreateGameObjectPool<TestGameObjectPoolable>(
                prefab: prefab,
                createFunc: () => 
                {
                    var go = Instantiate(prefab, transform);
                    return go as TestGameObjectPoolable;
                },
                onSpawn: obj => { Debug.Log($"GameObject被取出: {obj.name}"); },
                onRecycle: obj => { Debug.Log($"GameObject被回收: {obj.name}"); },
                onDestroy: obj => { Debug.Log($"GameObject被销毁: {obj.name}"); },
                initialCapacity: 5,
                maxSize: 20,
                isDynamic: true,
                poolRoot: transform
            );
            
            Debug.Log("GameObject对象池创建成功");
        }
        
        [ContextMenu("从GameObject对象池获取对象")]
        public void SpawnFromGameObjectPool()
        {
            if (_gameObjectPool == null)
            {
                Debug.LogError("请先创建GameObject对象池");
                return;
            }
            
            for (int i = 0; i < spawnCount; i++)
            {
                var obj = _gameObjectPool.Spawn();
                _activeObjects.Add(obj);
                Debug.Log($"获取GameObject: {obj.name}, 池大小: {_gameObjectPool.Count}");
            }
        }
        
        [ContextMenu("回收GameObject对象")]
        public void RecycleToGameObjectPool()
        {
            if (_gameObjectPool == null || prefab == null)
            {
                Debug.LogError("请先创建GameObject对象池和设置预制体");
                return;
            }
            
            int count = Mathf.Min(recycleCount, _activeObjects.Count);
            for (int i = 0; i < count; i++)
            {
                if (_activeObjects.Count > 0)
                {
                    var obj = _activeObjects[_activeObjects.Count - 1];
                    _activeObjects.RemoveAt(_activeObjects.Count - 1);
                    _gameObjectPool.Recycle(obj);
                    Debug.Log($"回收GameObject: {obj.name}, 池大小: {_gameObjectPool.Count}");
                }
            }
        }
        
        [ContextMenu("获取GameObject对象池统计")]
        public void GetGameObjectPoolStatistics()
        {
            if (_gameObjectPool == null)
            {
                Debug.LogError("请先创建GameObject对象池");
                return;
            }
            
            var stats = _gameObjectPool.Statistics;
            Debug.Log($"GameObject对象池统计:");
            Debug.Log($"  总取出次数: {stats.TotalSpawned}");
            Debug.Log($"  总回收次数: {stats.TotalRecycled}");
            Debug.Log($"  最大并发数: {stats.MaxConcurrent}");
            Debug.Log($"  池溢出次数: {stats.PoolOverflows}");
            Debug.Log($"  当前池大小: {_gameObjectPool.Count}");
        }
    }
} 